package com.itlong.cloud.iot.service.server.impl;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.VO.SDKMessageV3;
import com.itlong.cloud.POJO.VO.sdk.v3.hw.*;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.ErrorCode;
import com.itlong.cloud.enumerate.ecode.SDKV3ErrorCodeEnum;
import com.itlong.cloud.iot.huawei.util.HuawTokenClient;
import com.itlong.cloud.iot.service.server.HuaWeiV3Service;
import com.itlong.cloud.properties.HuaWeiIotProperties;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.tool.HttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;

@Service
public class HuaWeiV3ServiceImpl implements HuaWeiV3Service {

    @Autowired
    HuawTokenClient huawTokenClient;

    @Autowired
    RedisService redisService;

    @Resource
    HuaWeiIotProperties huaWeiIotProperties;

    private static final Logger LOG = LoggerFactory.getLogger(HuaWeiV3ServiceImpl.class);

    private static final int timeout = 5000;//请求http接口超时时间

    private RestTemplate getRestTemplate() {
        SimpleClientHttpRequestFactory f = new SimpleClientHttpRequestFactory();
        f.setConnectTimeout(timeout);
        f.setReadTimeout(timeout);
        RestTemplate r = new RestTemplate();
        r.setRequestFactory(f);
        return r;
    }

    /*
        https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/075e638b380025032f5dc01cc8403111/devices/5e521fb3334dd4f337aea227_0000183200000079;
    */
    private String getUrl(String projectId, String deviceId) {
        String url = "https://iotdm.cn-north-4.myhuaweicloud.com/v5/iot/%s/devices/%s/commands";
        return String.format(url, projectId, deviceId);
    }

    private String getAccessToken() {
        return huawTokenClient.getAccessToken();
    }

    @Override
    public SDKMessageV3 submitCallElevator(SetTravelWrap setTravelWrap) {
        LOG.info("【submitCallElevator setTravelWrap】{}", setTravelWrap);
        String url = getUrl(huaWeiIotProperties.getProjectid(), setTravelWrap.getDeviceId());
        String requestId = setTravelWrap.getRequestId();
        SetTravel command = setTravelWrap.getSetTravel();
        HashMap<String, Object> h = new HashMap<>();
        h.put("X-Auth-Token", getAccessToken());
        String responseString;
        try {
            LOG.info("【submitCallElevator requestId url】{} {}", requestId, url);
            responseString = HttpUtil.sendPostRequestWithObject(getRestTemplate(), url, command, h, String.class, true);
        } catch (Exception e) {
            e.printStackTrace();
            LOG.info("【submitCallElevator requestId Exception】{} {}", requestId, e.getMessage());
            //如果接口超时则发一个关门指令，防止电梯空跑
            CancelTravelWrap cancelTravelWrap = makeCancelTravelWrap(requestId, setTravelWrap.getDeviceId(), setTravelWrap.getRobotId(), command.getParas().getSnr());
            submitCancelElevator(cancelTravelWrap);
            return new SDKMessageV3(SDKV3ErrorCodeEnum.SUBMIT_TO_IOT_TIMEOUT.getErrorCode(), requestId, "submitCallElevator");
        }
        LOG.info("【submitCallElevator requestId responseString】{} {}", requestId, responseString);
        CommandResponse response = JSONObject.parseObject(responseString, CommandResponse.class);
        if (response != null && response.getResponse().getResult_code() == 0) {
            if (response.getResponse().getParas().getMsgCode() == 0) {
                return new SDKMessageV3(BaseErrorCodeEnum.SUCCESS.getErrorCode(), requestId);
            } else {
                ErrorCode errorCode = new ErrorCode(12, response.getResponse().getParas().getMsgCode(), response.getResponse().getParas().getMsg());
                return new SDKMessageV3(errorCode, requestId);
            }
        }
        return new SDKMessageV3(SDKV3ErrorCodeEnum.PARSE_IOT_HTTP_ERROR.getErrorCode(), requestId, responseString);
    }

    @Override
    @Async
    public SDKMessageV3 submitCancelElevator(CancelTravelWrap cancelTravelWrap) {
        LOG.info("【submitCancelElevator cancelTravelWrap】{}", cancelTravelWrap);
        String url = getUrl(huaWeiIotProperties.getProjectid(), cancelTravelWrap.getDeviceId());
        String requestId = cancelTravelWrap.getRequestId();
        CancelTravel command = cancelTravelWrap.getCancelTravel();
        HashMap<String, Object> h = new HashMap<>();
        h.put("X-Auth-Token", getAccessToken());
        String responseString;
        try {
            LOG.info("【submitCancelElevator requestId url】{} {}", requestId, url);
            responseString = HttpUtil.sendPostRequestWithObject(getRestTemplate(), url, command, h, String.class, true);
        } catch (Exception e) {
            e.printStackTrace();
            LOG.info("【submitCancelElevator requestId Exception】{} {}", requestId, e.getMessage());
            return new SDKMessageV3(SDKV3ErrorCodeEnum.SUBMIT_TO_IOT_TIMEOUT.getErrorCode(), requestId, "submitCancelElevator");
        }
        LOG.info("【submitCancelElevator requestId responseString】{} {}", requestId, responseString);
        CommandResponse response = JSONObject.parseObject(responseString, CommandResponse.class);
        if (response != null && response.getResponse().getResult_code() == 0) {
            if (response.getResponse().getParas().getMsgCode() == 0) {
                return new SDKMessageV3(BaseErrorCodeEnum.SUCCESS.getErrorCode(), requestId);
            } else {
                return new SDKMessageV3(SDKV3ErrorCodeEnum.DEVICE_EXECUTE_ERROR.getErrorCode(), requestId);
            }
        }
        return new SDKMessageV3(SDKV3ErrorCodeEnum.PARSE_IOT_HTTP_ERROR.getErrorCode(), requestId, responseString);
    }

    @Override
    public SDKMessageV3 submitOpenDoor(DoorCtrlOpenWrap doorCtrlOpenWrap) {
        LOG.info("【submitOpenDoor doorCtrlOpenWrap】{}", doorCtrlOpenWrap);
        String url = getUrl(huaWeiIotProperties.getProjectid(), doorCtrlOpenWrap.getDeviceId());
        String requestId = doorCtrlOpenWrap.getRequestId();
        DoorCtrlOpen command = doorCtrlOpenWrap.getDoorCtrlOpen();
        HashMap<String, Object> h = new HashMap<>();
        h.put("X-Auth-Token", getAccessToken());
        String responseString;
        try {
            LOG.info("【submitOpenDoor requestId url】{} {}", requestId, url);
            responseString = HttpUtil.sendPostRequestWithObject(getRestTemplate(), url, command, h, String.class, true);
        } catch (Exception e) {
            e.printStackTrace();
            LOG.info("【submitOpenDoor requestId Exception】{} {}", requestId, e.getMessage());
            return new SDKMessageV3(SDKV3ErrorCodeEnum.SUBMIT_TO_IOT_TIMEOUT.getErrorCode(), requestId, "submitOpenDoor");
        }
        LOG.info("【submitOpenDoor requestId responseString】{} {}", requestId, responseString);
        CommandResponse response = JSONObject.parseObject(responseString, CommandResponse.class);
        if (response != null && response.getResponse().getResult_code() == 0) {
            if (response.getResponse().getParas().getMsgCode() == 0) {
                return new SDKMessageV3(BaseErrorCodeEnum.SUCCESS.getErrorCode(), requestId);
            } else {
                ErrorCode errorCode = new ErrorCode(12, response.getResponse().getParas().getMsgCode(), response.getResponse().getParas().getMsg());
                return new SDKMessageV3(errorCode, requestId);
            }
        }
        return new SDKMessageV3(SDKV3ErrorCodeEnum.PARSE_IOT_HTTP_ERROR.getErrorCode(), requestId, responseString);
    }

    @Override
    public SDKMessageV3 submitCloseDoor(DoorCtrlCloseWrap doorCtrlCloseWrap) {
        LOG.info("【submitCloseDoor doorCtrlCloseWrap】{}", doorCtrlCloseWrap);
        String url = getUrl(huaWeiIotProperties.getProjectid(), doorCtrlCloseWrap.getDeviceId());
        String requestId = doorCtrlCloseWrap.getRequestId();
        DoorCtrlClose command = doorCtrlCloseWrap.getDoorCtrlClose();
        HashMap<String, Object> h = new HashMap<>();
        h.put("X-Auth-Token", getAccessToken());
        String responseString;
        try {
            LOG.info("【submitCloseDoor requestId url】{} {}", requestId, url);
            responseString = HttpUtil.sendPostRequestWithObject(getRestTemplate(), url, command, h, String.class, true);
        } catch (Exception e) {
            e.printStackTrace();
            LOG.info("【submitCloseDoor requestId Exception】{} {}", requestId, e.getMessage());
            return new SDKMessageV3(SDKV3ErrorCodeEnum.SUBMIT_TO_IOT_TIMEOUT.getErrorCode(), requestId, "submitCloseDoor");
        }
        LOG.info("【submitCloseDoor requestId responseString】{} {}", requestId, responseString);
        CommandResponse response = JSONObject.parseObject(responseString, CommandResponse.class);
        if (response != null && response.getResponse().getResult_code() == 0) {
            if (response.getResponse().getParas().getMsgCode() == 0) {
                return new SDKMessageV3(BaseErrorCodeEnum.SUCCESS.getErrorCode(), requestId);
            } else {
                ErrorCode errorCode = new ErrorCode(12, response.getResponse().getParas().getMsgCode(), response.getResponse().getParas().getMsg());
                return new SDKMessageV3(errorCode, requestId);
            }
        }
        return new SDKMessageV3(SDKV3ErrorCodeEnum.PARSE_IOT_HTTP_ERROR.getErrorCode(), requestId, responseString);
    }

    private CancelTravelWrap makeCancelTravelWrap(String requestId, String deviceId, String robotId, String snr) {
        CancelTravelData cancelTravelData = new CancelTravelData();
        cancelTravelData.setRobotId(robotId);
        //
        CancelTravelCustomData cancelTravelCustomData = new CancelTravelCustomData();
        cancelTravelCustomData.setCmd("cancelTravel");
        cancelTravelCustomData.setData(cancelTravelData);
        //
        CancelTravelParas cancelTravelParas = new CancelTravelParas();
        cancelTravelParas.setSourceFrom("itlong");
        cancelTravelParas.setSnr(snr);
        cancelTravelParas.setCmd("robot");
        cancelTravelParas.setTimestamp(DateUtil.getTimestampString());
        cancelTravelParas.setCustomData(JSONObject.toJSONString(cancelTravelCustomData));
        //
        CancelTravel cancelTravel = new CancelTravel();
        cancelTravel.setService_id("SettingService");
        cancelTravel.setCommand_name("dataUpdate");
        cancelTravel.setParas(cancelTravelParas);
        //
        CancelTravelWrap cancelTravelWrap = new CancelTravelWrap();
        cancelTravelWrap.setRequestId(requestId);
        cancelTravelWrap.setDeviceId(deviceId);
        cancelTravelWrap.setCancelTravel(cancelTravel);
        //
        return cancelTravelWrap;
    }

}